﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Kira.Compiler.Bods
{
    [XmlElementMapping("DITransformCall", "name", "Validation")]
    public class DIValidation : BodsTransform
    {
        public String InputName
        {
            get
            {
                return this.GetElement("DIInputView").GetAttrbuteValue("name");
            }
        }

        public String PassOutputName
        {
            get
            {
                return this.GetElements("DISchema").Single(c => c.GetAttrbuteValue("name").Contains("Pass")).GetAttrbuteValue("name");
            }
        }

        public String FailOutputName
        {
            get
            {
                return this.GetElements("DISchema").Single(c => c.GetAttrbuteValue("name").Contains("Fail")).GetAttrbuteValue("name");
            }
        }

        public override IEnumerable<string> InputNames
        {
            get { return new string[] { this.InputName }; }
        }

        public override IEnumerable<string> OutputNames
        {
            get { return new string[] { this.PassOutputName, this.FailOutputName }; }
        }


        public IEnumerable<ValidationRule> Rules
        {
            get
            {
                return this.GetElement("DIAttributes")
                    .GetElement(c => c.ElementName == "DIAttribute" && c.GetAttrbuteValue("name") == "validation_rules")
                    .GetElement("Rules")
                    .GetElements<ValidationRule>();
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(GetComments("Validation"));
            sb.AppendLine("--passed");
            sb.Append("WITH ").Append(PassOutputName).AppendLine(" AS (")
                .Append("SELECT * FROM ").AppendLine(InputName);
            if (Rules.Count() > 0)
            {
                sb.Append("WHERE ").AppendLine(Rules.Select(c => c.ExpressionText).Aggregate((a, b) => a + " AND " + b));
            }
            sb.AppendLine(")");
            sb.AppendLine("--failed");
            sb.Append("WITH ").Append(PassOutputName).AppendLine(" AS (")
                .Append("SELECT * FROM ").AppendLine(InputName);
            if (Rules.Count() > 0)
            {
                sb.Append("WHERE NOT (").Append(Rules.Select(c => c.ExpressionText).Aggregate((a, b) => a + " AND " + b)).AppendLine(")");

            } sb.AppendLine(")");
            return sb.ToString();
        }

    }

    [XmlElementMapping("Column", "enableValidation")]
    public class ValidationRule : BodsElementBase
    {
        public String ExpressionText
        {
            get
            {
                return this.GetElement("Expression").GetElement("Custom").Value;
            }
        }
    }
}
